package com.zf.powerjob.worker.processor;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import tech.powerjob.common.enums.LogLevel;
import tech.powerjob.common.model.LogConfig;
import tech.powerjob.worker.core.processor.ProcessResult;
import tech.powerjob.worker.core.processor.TaskContext;
import tech.powerjob.worker.core.processor.WorkflowContext;
import tech.powerjob.worker.core.processor.sdk.BasicProcessor;
import tech.powerjob.worker.log.OmsLogger;
import tech.powerjob.worker.log.impl.OmsLocalLogger;

import java.util.Map;

/**
 * 自定义 Processor, Server端配置 该 Processor 的全类名来调度该 Processor，
 * 需要将 Processor 加入到 bean 容器中
 */
@Slf4j
@Component
public class SampleProcessor implements BasicProcessor {

    /**
     * <pre>
     * 一、当前运行的是工作流，任务在工作流中运行时：
     *      1、当没有给工作流传递参数时:
     *               TaskContext.getWorkflowContext().getData() 获取的工作流参数是 【{}】；
     *               TaskContext.getInstanceParams() 获取的参数是【null】；
     *               TaskContext.getJobParams() 获取的参数是 【先取任务节点配置的参数值，如果没有配置，则取任务定义中的参数值】
     *
     *      2、当给工作流传递参数，且格式不符合json格式时，实例参数的值就等于工作流的上下文，PowerJob内部代码判定 【 {"key":"value"}、 [{"key":"value"}] 】格式才是json, 【 ["aa","bb"]、[]、[{}]、[{},{}]、{} 】格式不是json
     *               TaskContext.getWorkflowContext().getData() 获取的工作流参数是 【 {"initParams":"工作流传参"} 】；
     *               TaskContext.getInstanceParams() 获取的参数是【 {"initParams":"工作流传参"} 】；
     *               TaskContext.getJobParams() 获取的参数是 【先取任务节点配置的参数值，如果没有配置，则取任务定义中的参数值】
     *
     *      3、当给工作流传递参数，且格式是json格式时，实例参数的值就等于工作流的上下文
     *               TaskContext.getWorkflowContext().getData() 获取的工作流参数是 【 工作流传参 】；
     *               TaskContext.getInstanceParams() 获取的参数是【 工作流传参 】；
     *               TaskContext.getJobParams() 获取的参数是 【先取任务节点配置的参数值，如果没有配置，则取任务定义中的参数值】
     *
     * 二、当前运行的是单个任务，任务不在工作流中运行时
     *      TaskContext.getWorkflowContext().getData() 获取的工作流参数是 【 {} 】；
     *      TaskContext.getInstanceParams() 获取的参数是【 运行时传递的参数 】；
     *      TaskContext.getJobParams() 获取的参数是 【任务定义中的参数值】
     * </pre>
     */
    @Override
    public ProcessResult process(TaskContext taskContext) throws Exception {

        // 在线日志，由其打印的日志，会被上传到 PowerJob Server 端，可以在 PowerJob Server 端页面任务实例中看到对应的日志
        OmsLogger omsLogger = taskContext.getOmsLogger();
        // 在线日志
        omsLogger.info("执行了 Test");

        // 本地日志
        log.info("执行了Test");

        // 任务定义中的 参数
        // 单独运行任务：任务定义中的参数值
        // 嵌入到工作流中运行时：优先取节点配置的参数，如果没有配置，再取任务定义中的参数值
        String jobParams = taskContext.getJobParams();
        System.out.println("任务参数：" + jobParams);

        // 参数运行时，传入的参数
        // 单独运行任务：任务传入什么就获取什么
        // 嵌入到工作流中运行：1、如果工作流没有传参，就返回 【 null 】；2、如果工作流参数不是 json 格式，就返回 【 {"initParams":"工作流传参"} 】；3、如果工作流参数是 json 格式，就返回 【 工作流传参 】
        String instanceParams = taskContext.getInstanceParams();
        System.out.println("运行参数：" + instanceParams);

        // 任务被整合成工作流时，可以获取整个工作流的上下文
        WorkflowContext workflowContext = taskContext.getWorkflowContext();
        // 上下文中数据：1、如果工作流没有传参，就返回 【 {} 】；2、如果工作流参数不是 json 格式，就返回 【 {"initParams":"工作流传参"} 】；3、如果工作流参数是 json 格式，就返回 【 工作流传参 】
        Map<String, String> data = workflowContext.getData();
        System.out.println("工作流上下文：" + data);


        // 任务执行结果
        // 成功
        return new ProcessResult(true);
        // 失败
        // return new ProcessResult(false, "错误信息");
    }

    /**
     * 手动创建 TaskContext, 用在非定时任务，但是会调用到 Processor#process(TaskContext) 方法的场景
     */
    public TaskContext getEmptyTaskContext() {
        TaskContext context = new TaskContext();
        // 设置在线日志，使用本地日志，将日志打印到本地
        context.setOmsLogger(new OmsLocalLogger(new LogConfig().setLevel(LogLevel.INFO.getV())));
        // 设置任务定义参数
        context.setJobParams("{}");
        // 设置任务运行时传入的参数
        context.setInstanceParams("{}");
        // 设置一个空的工作流上下文
        context.setWorkflowContext(new WorkflowContext(null, ""));
        return context;
    }

}
